package com.dage.salesflow.es;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.elasticsearch.core.CreateResponse;
import co.elastic.clients.elasticsearch.core.DeleteResponse;
import co.elastic.clients.elasticsearch.core.SearchResponse;
import co.elastic.clients.elasticsearch.core.UpdateResponse;
import co.elastic.clients.elasticsearch.core.search.Hit;
import co.elastic.clients.elasticsearch.indices.CreateIndexRequest;
import co.elastic.clients.elasticsearch.indices.CreateIndexResponse;
import co.elastic.clients.transport.endpoints.BooleanResponse;
import com.jfinal.kit.Kv;
import io.jboot.aop.annotation.Bean;
import io.jboot.exception.JbootException;
import io.jboot.utils.CollectionUtil;

import java.io.IOException;
import java.util.List;

/**
 * 这里只是简单的建立索引，只有id和name两个mapping（使用了ik_max_word分词器）
 * 查询时，只根据name匹配返回分数最高的一条记录
 * 使用ElasticsearchClient需要对es底层命令比较熟悉
 * 如果想要更方便的使用，需要更复杂的封装
 * 这个嘛。。。我们有缘再见把。。
 */
@Bean
public class CustomerProfileES {
	public static final String indexName = "customer_profile";
	ElasticsearchClient elasticsearchClient = ElasticSearchPlugin.getElasticsearchClient();

	public static void init() throws IOException {
		ElasticsearchClient elasticsearchClient = ElasticSearchPlugin.getElasticsearchClient();
		//			DeleteIndexResponse response = elasticsearchClient.indices().delete(new DeleteIndexRequest.Builder().index(indexName).build());
		//			Map<String, Property> fields = Collections.singletonMap("keyword", Property.of(p -> p.keyword(k ->k.ignoreAbove(256))));
		//			Property text = Property.of(p -> p.text(t -> t.fields(fields)));
		BooleanResponse existsResponse = elasticsearchClient.indices().exists(b -> b.index(indexName));
		if (!existsResponse.value()) {
			CreateIndexResponse response = elasticsearchClient.indices().create(new CreateIndexRequest.Builder()
					.index(indexName)
					.mappings(
							m -> m.properties("name", p -> p.text(tp -> tp.analyzer("ik_max_word")))
					)
					.settings(is -> is.numberOfReplicas("0"))
					.build());
			if (!response.acknowledged()) {
				throw new JbootException(indexName + "索引创建失败");
			}
		}
	}

	/**
	 * 插入
	 */
	public CreateResponse create(Integer id, String name) {
		try {
			return elasticsearchClient.create(builder -> builder.index(indexName)
					.id(id.toString())
					.document(Kv.by("name", name)));
		} catch (IOException e) {
			throw new JbootException(e);
		}
	}

	/**
	 * 更新
	 */
	public UpdateResponse update(Integer id, String name) {
		try {
			return elasticsearchClient.update(builder -> builder.index(indexName)
					.id(id.toString())
					.doc(Kv.by("name", name)), Kv.class);
		} catch (IOException e) {
			throw new JbootException(e);
		}
	}

	/**
	 * 删除
	 */
	public DeleteResponse delete(Object id) {
		try {
			return elasticsearchClient.delete(builder -> builder.index(indexName)
					.id(id.toString()));
		} catch (IOException e) {
			throw new JbootException(e);
		}
	}

	/**
	 * 根据客户名查找第一个
	 *
	 * @param name
	 */
	public Hit matchFirst(String name) {
		try {
			SearchResponse search = elasticsearchClient.search(builder -> builder.index(indexName)
					.source(sb -> sb.fetch(false))
					.query(b -> b.match(mb -> mb.field("name").query(name))), Kv.class);
			List<Hit> hits = search.hits().hits();
			if (!CollectionUtil.isEmpty(hits)) {
				return hits.get(0);
			} else {
				return null;
			}
		} catch (IOException e) {
			throw new JbootException(e);
		}
	}
}
